package com.aop.retry;

import lombok.extern.log4j.Log4j2;

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;

/**
 * @Package: com.aop.retry
 * @ClassName: RetryTemplate
 * @Author: h2cloud
 * @CreateTime: 2022/11/19 12:33 上午
 * @Description:
 */
// https://cloud.tencent.com/developer/article/1038304
@Log4j2
public abstract class RetryTemplate {

	// 重试次数
	private int retryTime = 10;
	// 重试的睡眠时间
	private int sleepTime = 1000;

	public int getSleepTime() {
		return sleepTime;
	}

	public RetryTemplate setSleepTime(int sleepTime) {
		if (sleepTime < 0) {
			throw new IllegalArgumentException("sleepTime should equal or bigger than 0");
		}

		this.sleepTime = sleepTime;
		return this;
	}

	public int getRetryTime() {
		return retryTime;
	}

	public RetryTemplate setRetryTime(int retryTime) {
		if (retryTime <= 0) {
			throw new IllegalArgumentException("retryTime should bigger than 0");
		}

		this.retryTime = retryTime;
		return this;
	}

	/**
	 * 重试的业务执行代码
	 * 失败时请抛出一个异常
	 * <p>
	 * todo 确定返回的封装类，根据返回结果的状态来判定是否需要重试
	 *
	 * @return
	 */
	protected abstract Object doBiz() throws Exception;


	public Object execute() throws InterruptedException {
		for (int i = 0; i < retryTime; i++) {
			try {
				return doBiz();
			} catch (Exception e) {
				log.error("业务执行出现异常，e: {}", e);
				Thread.sleep(sleepTime);
			}
		}

		return null;
	}
}
